from DebugLogger import *
from reactorblock import *
from accident import *
from gamestate import *
from soundmachine import *

class GlobalStates(object):
    Round_Number = 0
    Radiation_Level = RADIATION_INITIAL_VALUE
    Core_Temperature = CORE_TEMPERATURE_INTIAL_VALUE
    AllCounterMeasuresCompleteList = []
    CounterMeasuresActionList = []
    AccidentsOccuredList = []
    Reactors = (
        Reactorblock(),
        Reactorblock(),
        Reactorblock(),
        Reactorblock() )
    
    
    @staticmethod
    def AssembleStatusReport():
        newAccidentstr = ""
        accidentID = -1
        if len(GlobalStates.AccidentsOccuredList) > 0:
           accidentID = GlobalStates.AccidentsOccuredList[len(GlobalStates.AccidentsOccuredList)-1].accident 
        
        if accidentID == ACCIDENT_BROKEN_PIPES_INNER_COOLING_SYSTEM:
            newAccidentstr = " - Pipes broken!"
        elif accidentID == ACCIDENT_REACTOR_OUTER_CORE_EXPLOSION:
            newAccidentstr = " - Outer core explosion!"
        elif accidentID == ACCIDENT_REACTOR_FRACTURE:
            newAccidentstr = " - Reactor fracture!"
        elif accidentID == ACCIDENT_PARTIAL_MELTDOWN:
            newAccidentstr = " - Partial meltdown!"
        elif accidentID == ACCIDENT_FULL_MELTDOWN:
            newAccidentstr = " - Full meltdown!"
        elif accidentID == ACCIDENT_REACTOR_INNER_CORE_EXPLOSION:
            newAccidentstr = " - Inner core explosion!"
        
        stringArray = []
        stringArray.append("Status Report: Round " + str(len(GlobalStates.CounterMeasuresActionList)) + " OF 9  " + newAccidentstr )        
        stringArray.append("-----------------------------------------------------------------------------")                
        stringArray.append("Reactor core temperature: " + str(GlobalStates.Core_Temperature) + " deg C" + " Radiation level: " + str(GlobalStates.Radiation_Level) + "  mSv")
        stringArray.append("")
        for action in GlobalStates.AllCounterMeasuresCompleteList:
            increase_decrease_string = " "
            if action._is_done:
                if action.roundTemperatureDecrease > 0:
                   increase_decrease_string += "-" + str(action.roundTemperatureDecrease) + " deg C"
                if action.roundRadiationIncrease > 0:
                   increase_decrease_string += " +" + str(action.roundRadiationIncrease) + " mSv" 
                if action.roundRadiationDecrease > 0:
                   increase_decrease_string += " -" + str(action.roundRadiationDecrease) + " mSv" 
            
            action_index = str(GlobalStates.AllCounterMeasuresCompleteList.index(action) ) 
            
            stringArray.append( action.description )
            stringArray.append( "\t" + action.state_msg + increase_decrease_string )            
        
        stringArray.append("--")
        
        for accident in GlobalStates.AccidentsOccuredList:
            increase_string = " "
            if accident.increased_radiation > 0:
                increase_string += "+ "  + str(accident.increased_radiation + " mSv") 
            stringArray.append("Accident: " + accident.description + increase_string)
                
        return stringArray      
            #action.
        
    
    @staticmethod
    def ResetGlobalStates():
        GlobalStates.Radiation_Level = RADIATION_INITIAL_VALUE
        GlobalStates.Core_Temperature = CORE_TEMPERATURE_INTIAL_VALUE
        GlobalStates.CounterMeasuresActionList = []
        GlobalStates.AccidentsOccuredList = []
        #SoundMachine.StopAllSounds()
        GlobalStates.Reactors = (
            Reactorblock(),
            Reactorblock(),
            Reactorblock(),
            Reactorblock() )
    
    @staticmethod
    def IncreaseCoreTemperature(delta):
        DebugLogger.DebugOut("Increase temperature by " + str(delta) )
        GlobalStates.Core_Temperature += delta
        return delta

    
    @staticmethod   
    def DecreaseCoreTemperature(delta):
        DebugLogger.DebugOut("Decrease temperature by " + str(delta) )
        initial_value = GlobalStates.Core_Temperature
        GlobalStates.Core_Temperature -= delta
        if GlobalStates.Core_Temperature < CORE_TEMPERATURE_INTIAL_VALUE:
            GlobalStates.Core_Temperature = CORE_TEMPERATURE_INTIAL_VALUE
        return initial_value - GlobalStates.Core_Temperature;
        
    @staticmethod
    def IncreaseRadiationLevel(delta):
        DebugLogger.DebugOut("Increase radiation by " + str(delta) )
        GlobalStates.Radiation_Level += delta
        return delta
    
    @staticmethod   
    def DecreaseRadiationLevel(delta):
        DebugLogger.DebugOut("Decrease radiation by " + str(delta) )
        initial_value = GlobalStates.Radiation_Level
        GlobalStates.Radiation_Level -= delta
        if GlobalStates.Radiation_Level < RADIATION_INITIAL_VALUE:
                GlobalStates.Radiation_Level = RADIATION_INITIAL_VALUE
        return initial_value - GlobalStates.Radiation_Level
       
    @staticmethod  
    def AddCounterMeasureAction(action):
        GlobalStates.CounterMeasuresActionList.append(action)


    @staticmethod        
    def PerformCounterMeasureActions():
        for act in GlobalStates.AllCounterMeasuresCompleteList:
            act.perform()

    @staticmethod
    def IsActionActive(id):
        for act in GlobalStates.CounterMeasuresActionList:
            if id == act.action:
                return True
        
        return False
    
    @staticmethod
    def GetAction(id):
        for act in GlobalStates.CounterMeasuresActionList:
            if id == act.action:
                return act
            
        return None
    
    @staticmethod
    def GetActionIndex(id):
        for act in GlobalStates.CounterMeasuresActionList:
            if id == act.action:
                return GlobalStates.CounterMeasuresActionList.index(act)

        return -1

    @staticmethod
    def AddAccident(accident):
        if GlobalStates.AccidentsOccuredList.__contains__(accident) == False:
            GlobalStates.AccidentsOccuredList.append(accident)
            
            length = GlobalStates.CounterMeasuresActionList.__len__()            
            if length == 0:
                GlobalStates.SetAccidentToReactor(accident, 0)
            else:
                actionIndex = GlobalStates.GetActionIndex(GlobalStates.CounterMeasuresActionList[0])
                if accident.accident == ACCIDENT_BROKEN_PIPES_INNER_COOLING_SYSTEM:
                    GlobalStates.SetAccidentToReactor(accident,(actionIndex)%4 )
                elif accident.accident == ACCIDENT_REACTOR_OUTER_CORE_EXPLOSION:
                    GlobalStates.SetAccidentToReactor(accident,(actionIndex+4)%4 )
                elif accident.accident == ACCIDENT_REACTOR_FRACTURE:
                    GlobalStates.SetAccidentToReactor(accident,(actionIndex+7)%4 )                    
                elif accident.accident == ACCIDENT_PARTIAL_MELTDOWN:
                    GlobalStates.SetAccidentToReactor(accident,(actionIndex+9)%4 )
                elif accident.accident == ACCIDENT_FULL_MELTDOWN:
                    GlobalStates.SetAccidentToReactor(accident,(actionIndex+9)%4 )                    
                elif accident.accident == ACCIDENT_REACTOR_INNER_CORE_EXPLOSION:
                    GlobalStates.SetAccidentToReactor(accident,(actionIndex+15)%4 )                    
                    

    
    @staticmethod            
    def SetAccidentToReactor(accident,index):  
        GlobalStates.Reactors[index].temperature = GlobalStates.Core_Temperature
        accident.reactor_index = index
        
        if accident.accident == ACCIDENT_BROKEN_PIPES_INNER_COOLING_SYSTEM:            
            GlobalStates.Reactors[index].animation = REACTOR_ANIM_BROKEN_PIPES_INNER_COOLING_SYSTEM
            GlobalStates.Reactors[index].endstate = REACTOR_STATE_INTACT
            #SoundMachine.PlayAccidentSound(SOUND_ACCIDENT_LEAKING_GAS)    
                                                            
        elif accident.accident == ACCIDENT_REACTOR_FRACTURE:
            GlobalStates.Reactors[index].animation = REACTOR_ANIM_FRACTURE
            GlobalStates.Reactors[index].endstate = REACTOR_STATE_FRACTURED
            #SoundMachine.PlayAccidentSound(SOUND_ACCIDENT_FRATURE)
            
        elif accident.accident == ACCIDENT_REACTOR_OUTER_CORE_EXPLOSION:
            GlobalStates.Reactors[index].animation = REACTOR_ANIM_OUTER_CORE_EXPLOSION
            GlobalStates.Reactors[index].endstate = REACTOR_STATE_FRACTURED
            #SoundMachine.PlayAccidentSound(SOUND_ACCIDENT_OUTER_EXPLOSION)           
            
        elif accident.accident == ACCIDENT_PARTIAL_MELTDOWN:
            GlobalStates.Reactors[index].animation = REACTOR_ANIM_MELTDOWN
            GlobalStates.Reactors[index].endstate = REACTOR_STATE_HEAVY_DAMAGED
            #SoundMachine.PlayAccidentSound(SOUND_ACCIDENT_PARTIAL_MELTDOWN)
            
        elif accident.accident == ACCIDENT_FULL_MELTDOWN:
            GlobalStates.Reactors[index].animation = REACTOR_ANIM_MELTDOWN
            GlobalStates.Reactors[index].endstate = REACTOR_STATE_HEAVY_DAMAGED
            #SoundMachine.PlayAccidentSound(SOUND_ACCIDENT_FULL_MELTDOWN)
            
        elif accident.accident == ACCIDENT_REACTOR_INNER_CORE_EXPLOSION:            
            GlobalStates.Reactors[index].animation = REACTOR_ANIM_INNER_CORE_EXPLOSION
            GlobalStates.Reactors[index].endstate = REACTOR_STATE_DESTROYED          
            #SoundMachine.PlayAccidentSound(SOUND_ACCIDENT_INNER_EXPLOSION)
            
    @staticmethod    
    def PerformAccidents():
        for acc in GlobalStates.AccidentsOccuredList:
            acc.perform()
            